<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>勾股定理逆定理与三角形形状关系</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
            color: white;
            min-height: 100vh;
            padding: 20px;
            overflow-x: hidden;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        
        header {
            text-align: center;
            margin-bottom: 30px;
            padding: 30px;
            background: rgba(0, 0, 0, 0.4);
            border-radius: 20px;
            box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
            position: relative;
            overflow: hidden;
        }
        
        header::before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: 
                radial-gradient(circle at 20% 30%, rgba(255, 215, 0, 0.1) 0%, transparent 40%),
                radial-gradient(circle at 80% 70%, rgba(77, 171, 247, 0.1) 0%, transparent 40%);
            pointer-events: none;
        }
        
        h1 {
            font-size: 3.2rem;
            margin-bottom: 15px;
            text-shadow: 0 3px 12px rgba(0, 0, 0, 0.6);
            background: linear-gradient(to right, #ffd700, #ff8a00);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            position: relative;
            z-index: 2;
        }
        
        .subtitle {
            font-size: 1.5rem;
            opacity: 0.9;
            max-width: 800px;
            margin: 0 auto;
            line-height: 1.6;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
            position: relative;
            z-index: 2;
        }
        
        .content {
            display: flex;
            flex-wrap: wrap;
            gap: 30px;
            margin-bottom: 40px;
        }
        
        .control-panel {
            flex: 1;
            min-width: 320px;
            background: rgba(0, 0, 0, 0.3);
            padding: 25px;
            border-radius: 20px;
            box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .visualization {
            flex: 2;
            min-width: 500px;
            background: rgba(255, 255, 255, 0.08);
            backdrop-filter: blur(10px);
            border-radius: 20px;
            padding: 25px;
            box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
            border: 1px solid rgba(255, 255, 255, 0.1);
            display: flex;
            flex-direction: column;
            align-items: center;
            position: relative;
        }
        
        .control-group {
            margin-bottom: 25px;
            padding: 15px;
            background: rgba(0, 0, 0, 0.2);
            border-radius: 15px;
        }
        
        h2 {
            font-size: 2.0rem;
            margin-bottom: 20px;
            color: #ffd700;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
            position: relative;
            padding-left: 15px;
        }
        
        h2::before {
            content: "";
            position: absolute;
            left: 0;
            top: 50%;
            transform: translateY(-50%);
            height: 70%;
            width: 5px;
            background: linear-gradient(to bottom, #ffd700, #ff8a00);
            border-radius: 3px;
        }
        
        h3 {
            font-size: 1.5rem;
            margin-bottom: 15px;
            color: #4dabf7;
            display: flex;
            align-items: center;
        }
        
        h3 i {
            margin-right: 10px;
            font-size: 1.3rem;
        }
        
        label {
            display: block;
            margin-bottom: 10px;
            font-size: 1.2rem;
            display: flex;
            justify-content: space-between;
        }
        
        input[type="range"] {
            width: 100%;
            height: 12px;
            border-radius: 10px;
            background: rgba(255, 255, 255, 0.1);
            outline: none;
            margin: 15px 0;
            -webkit-appearance: none;
        }
        
        input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 25px;
            height: 25px;
            border-radius: 50%;
            background: #ffd700;
            cursor: pointer;
            box-shadow: 0 0 10px rgba(255, 215, 0, 0.5);
        }
        
        .value-display {
            background: rgba(255, 255, 255, 0.15);
            padding: 10px 15px;
            border-radius: 10px;
            font-size: 1.2rem;
            margin-top: 5px;
            display: flex;
            justify-content: space-between;
        }
        
        .preset-buttons {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
            gap: 12px;
            margin-top: 20px;
        }
        
        .preset-btn {
            background: rgba(77, 171, 247, 0.2);
            border: 1px solid rgba(77, 171, 247, 0.5);
            color: white;
            padding: 12px;
            border-radius: 10px;
            cursor: pointer;
            transition: all 0.3s ease;
            font-size: 1.1rem;
            text-align: center;
        }
        
        .preset-btn:hover {
            background: rgba(77, 171, 247, 0.4);
            transform: translateY(-3px);
        }
        
        #drawBtn {
            background: linear-gradient(to right, #ff8a00, #da1b60);
            color: white;
            border: none;
            padding: 16px;
            font-size: 1.2rem;
            border-radius: 12px;
            cursor: pointer;
            transition: all 0.3s ease;
            width: 100%;
            font-weight: bold;
            letter-spacing: 1px;
            margin-top: 15px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        }
        
        #drawBtn:hover {
            transform: translateY(-5px);
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
        }
        
        .result {
            background: rgba(0, 0, 0, 0.4);
            padding: 20px;
            border-radius: 15px;
            margin-top: 20px;
            font-size: 1.2rem;
            line-height: 1.6;
            min-height: 150px;
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .triangle-type {
            font-size: 2.0rem;
            font-weight: bold;
            margin: 15px 0;
            text-align: center;
            padding: 15px;
            border-radius: 12px;
            background: rgba(0, 0, 0, 0.3);
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
        }
        
        .acute { 
            color: #4dabf7; 
            text-shadow: 0 0 10px rgba(77, 171, 247, 0.7);
        }
        .right { 
            color: #51cf66;
            text-shadow: 0 0 10px rgba(81, 207, 102, 0.7);
        }
        .obtuse { 
            color: #ff6b6b;
            text-shadow: 0 0 10px rgba(255, 107, 107, 0.7);
        }
        
        #triangleCanvas {
            background: rgba(255, 255, 255, 0.05);
            border-radius: 12px;
            margin: 20px 0;
            box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
            width: 100%;
            max-width: 600px;
        }
        
        .explanation {
            background: rgba(0, 0, 0, 0.3);
            padding: 35px;
            border-radius: 20px;
            margin-top: 30px;
            box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .theorem {
            background: rgba(255, 255, 255, 0.08);
            padding: 25px;
            border-left: 5px solid #ffd700;
            margin: 25px 0;
            border-radius: 0 15px 15px 0;
            position: relative;
            overflow: hidden;
        }
        
        .theorem::before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: 
                radial-gradient(circle at 10% 20%, rgba(255, 215, 0, 0.05) 0%, transparent 40%);
            pointer-events: none;
        }
        
        .formula {
            font-size: 1.7rem;
            text-align: center;
            margin: 20px 0;
            padding: 20px;
            background: rgba(0, 0, 0, 0.3);
            border-radius: 12px;
            font-family: 'Cambria', serif;
            border: 1px solid rgba(255, 255, 255, 0.1);
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
        }
        
        .steps {
            margin: 30px 0;
        }
        
        .step {
            display: flex;
            margin-bottom: 25px;
            align-items: flex-start;
            background: rgba(255, 255, 255, 0.05);
            padding: 20px;
            border-radius: 12px;
            transition: transform 0.3s ease;
        }
        
        .step:hover {
            transform: translateY(-5px);
            background: rgba(255, 255, 255, 0.08);
        }
        
        .step-number {
            background: linear-gradient(to bottom, #ffd700, #ff8a00);
            color: #1a2a6c;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            justify-content: center;
            align-items: center;
            font-weight: bold;
            font-size: 1.3rem;
            margin-right: 20px;
            flex-shrink: 0;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
        }
        
        .step-content {
            flex: 1;
        }
        
        .step-content h4 {
            font-size: 1.4rem;
            margin-bottom: 10px;
            color: #ffd700;
        }
        
        .footer {
            text-align: center;
            margin-top: 40px;
            padding: 20px;
            color: rgba(255, 255, 255, 0.7);
            font-size: 1.1rem;
            border-top: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        @media (max-width: 768px) {
            .content {
                flex-direction: column;
            }
            
            .visualization {
                min-width: 100%;
            }
            
            h1 {
                font-size: 2.5rem;
            }
            
            .subtitle {
                font-size: 1.2rem;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>勾股定理逆定理与三角形形状关系</h1>
            <p class="subtitle">探索三角形边长与角度类型的数学关系 - 通过可视化工具理解勾股定理的逆定理</p>
        </header>
        
        <div class="content">
            <div class="control-panel">
                <h2>三角形参数控制</h2>
                
                <div class="control-group">
                    <h3><i>↔️</i> 调整三角形边长</h3>
                    
                    <label for="sideA">
                        <span>边 a 长度：</span>
                        <span id="sideAValue">5.0</span>
                    </label>
                    <input type="range" id="sideA" min="1" max="15" value="5" step="0.1">
                    
                    <label for="sideB">
                        <span>边 b 长度：</span>
                        <span id="sideBValue">5.0</span>
                    </label>
                    <input type="range" id="sideB" min="1" max="15" value="5" step="0.1">
                    
                    <label for="sideC">
                        <span>边 c 长度：</span>
                        <span id="sideCValue">7.1</span>
                    </label>
                    <input type="range" id="sideC" min="1" max="15" value="7.1" step="0.1">
                    
                    <div class="preset-buttons">
                        <div class="preset-btn" data-a="3" data-b="4" data-c="5">直角 (3-4-5)</div>
                        <div class="preset-btn" data-a="5" data-b="5" data-c="5">等边 (5-5-5)</div>
                        <div class="preset-btn" data-a="4" data-b="5" data-c="6">锐角 (4-5-6)</div>
                        <div class="preset-btn" data-a="5" data-b="5" data-c="8">钝角 (5-5-8)</div>
                    </div>
                    
                    <button id="drawBtn">更新三角形</button>
                </div>
                
                <div class="result">
                    <div id="triangleType" class="triangle-type">钝角三角形</div>
                    <div id="resultDetails">
                        当 a² + b² < c² 时，三角形为钝角三角形（c边所对的角大于90°）。
                    </div>
                </div>
            </div>
            
            <div class="visualization">
                <h2>三角形形状可视化</h2>
                <canvas id="triangleCanvas" width="600" height="450"></canvas>
                <div id="visualInfo">当前边长: a=5.0, b=5.0, c=7.1 | 类型: 钝角三角形</div>
            </div>
        </div>
        
        <div class="explanation">
            <h2>勾股定理及其逆定理</h2>
            
            <div class="theorem">
                <h3>勾股定理（正定理）</h3>
                <p>在直角三角形中，两条直角边的平方和等于斜边的平方。</p>
                <div class="formula">a² + b² = c²</div>
                <p>其中c是斜边（直角的对边），a和b是两条直角边。</p>
            </div>
            
            <div class="theorem">
                <h3>勾股定理逆定理</h3>
                <p>如果一个三角形的三边满足 a² + b² = c²，那么这个三角形是直角三角形，且c边所对的角是直角。</p>
                <p>更一般地，我们可以通过三边关系判断三角形的形状：</p>
                <div class="formula">
                    若 a² + b² = c²  → 直角三角形<br>
                    若 a² + b² > c²  → 锐角三角形<br>
                    若 a² + b² < c²  → 钝角三角形
                </div>
                <p>（其中c是三角形的最长边）</p>
            </div>
            
            <div class="steps">
                <h3>判断三角形类型的步骤</h3>
                
                <div class="step">
                    <div class="step-number">1</div>
                    <div class="step-content">
                        <h4>确定最长边</h4>
                        <p>找出三角形三条边中最长的一条边，标记为c。另外两条边标记为a和b。</p>
                    </div>
                </div>
                
                <div class="step">
                    <div class="step-number">2</div>
                    <div class="step-content">
                        <h4>计算平方和</h4>
                        <p>计算 a² + b² 的值，并与 c² 进行比较。</p>
                    </div>
                </div>
                
                <div class="step">
                    <div class="step-number">3</div>
                    <div class="step-content">
                        <h4>比较并判断</h4>
                        <ul>
                            <li>若 a² + b² = c² → 直角三角形（c边所对的角为直角）</li>
                            <li>若 a² + b² > c² → 锐角三角形（所有角都小于90°）</li>
                            <li>若 a² + b² < c² → 钝角三角形（c边所对的角大于90°）</li>
                        </ul>
                    </div>
                </div>
                
                <div class="step">
                    <div class="step-number">4</div>
                    <div class="step-content">
                        <h4>验证三角形不等式</h4>
                        <p>确保输入的三边满足三角形的基本条件：任意两边之和大于第三边。</p>
                        <p>a + b > c, a + c > b, b + c > a</p>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="footer">
            <p>勾股定理逆定理可视化工具 | 数学教育交互演示 | © 2025小憨涵数学实验室</p>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const canvas = document.getElementById('triangleCanvas');
            const ctx = canvas.getContext('2d');
            const sideAInput = document.getElementById('sideA');
            const sideBInput = document.getElementById('sideB');
            const sideCInput = document.getElementById('sideC');
            const sideAValue = document.getElementById('sideAValue');
            const sideBValue = document.getElementById('sideBValue');
            const sideCValue = document.getElementById('sideCValue');
            const drawBtn = document.getElementById('drawBtn');
            const triangleTypeEl = document.getElementById('triangleType');
            const resultDetailsEl = document.getElementById('resultDetails');
            const visualInfoEl = document.getElementById('visualInfo');
            const presetBtns = document.querySelectorAll('.preset-btn');
            
            // 初始值
            let a = 5.0;
            let b = 5.0;
            let c = 7.1;
            
            // 更新滑块显示值
            function updateSliderValues() {
                sideAValue.textContent = a.toFixed(1);
                sideBValue.textContent = b.toFixed(1);
                sideCValue.textContent = c.toFixed(1);
            }
            
            // 绘制三角形
            function drawTriangle() {
                // 清除画布
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                
                // 设置三角形位置和大小
                const padding = 80;
                const centerX = canvas.width / 2;
                const centerY = canvas.height / 2 + 40;
                const scale = 25;
                
                // 计算角度
                const angleA = Math.acos((b*b + c*c - a*a) / (2*b*c));
                const angleB = Math.acos((a*a + c*c - b*b) / (2*a*c));
                const angleC = Math.acos((a*a + b*b - c*c) / (2*a*b));
                
                // 计算顶点坐标
                const pointA = { x: centerX, y: centerY };
                const pointB = { 
                    x: centerX + c * scale, 
                    y: centerY 
                };
                const pointC = { 
                    x: centerX + b * scale * Math.cos(angleA), 
                    y: centerY - b * scale * Math.sin(angleA)
                };
                
                // 绘制三角形
                ctx.beginPath();
                ctx.moveTo(pointA.x, pointA.y);
                ctx.lineTo(pointB.x, pointB.y);
                ctx.lineTo(pointC.x, pointC.y);
                ctx.closePath();
                
                // 确定三角形类型
                const sides = [a, b, c];
                sides.sort((x, y) => x - y);
                const min = sides[0];
                const mid = sides[1];
                const max = sides[2];
                
                const minSq = min * min;
                const midSq = mid * mid;
                const maxSq = max * max;
                
                const sum = minSq + midSq;
                const tolerance = 0.0001;
                
                let triangleType, angleType, description;
                
                if (Math.abs(sum - maxSq) < tolerance) {
                    triangleType = "直角三角形";
                    angleType = "直角";
                    description = `因为 ${min}² + ${mid}² = ${max}² (${minSq} + ${midSq} = ${maxSq})，满足勾股定理逆定理，所以这是一个直角三角形。`;
                } else if (sum > maxSq) {
                    triangleType = "锐角三角形";
                    angleType = "锐角";
                    description = `因为 ${min}² + ${mid}² > ${max}² (${minSq} + ${midSq} = ${sum} > ${maxSq})，所以这是一个锐角三角形（所有角都小于90°）。`;
                } else {
                    triangleType = "钝角三角形";
                    angleType = "钝角";
                    description = `因为 ${min}² + ${mid}² < ${max}² (${minSq} + ${midSq} = ${sum} < ${maxSq})，所以这是一个钝角三角形（${max}边所对的角大于90°）。`;
                }
                
                // 设置样式
                if (angleType === '直角') {
                    ctx.strokeStyle = '#51cf66';
                    ctx.fillStyle = 'rgba(81, 207, 102, 0.15)';
                } else if (angleType === '锐角') {
                    ctx.strokeStyle = '#4dabf7';
                    ctx.fillStyle = 'rgba(77, 171, 247, 0.15)';
                } else {
                    ctx.strokeStyle = '#ff6b6b';
                    ctx.fillStyle = 'rgba(255, 107, 107, 0.15)';
                }
                
                ctx.lineWidth = 4;
                ctx.stroke();
                ctx.fill();
                
                // 标记顶点
                ctx.fillStyle = 'white';
                ctx.font = 'bold 20px Arial';
                ctx.fillText('A', pointA.x - 30, pointA.y + 5);
                ctx.fillText('B', pointB.x + 15, pointB.y + 5);
                ctx.fillText('C', pointC.x, pointC.y - 20);
                
                // 标记边长
                ctx.fillStyle = '#ffd700';
                ctx.font = 'bold 16px Arial';
                
                // 边AB (c)
                const midAB = {
                    x: (pointA.x + pointB.x) / 2,
                    y: (pointA.y + pointB.y) / 2 + 20
                };
                ctx.fillText(`c = ${c.toFixed(1)}`, midAB.x, midAB.y);
                
                // 边BC (a)
                const midBC = {
                    x: (pointB.x + pointC.x) / 2 + 15,
                    y: (pointB.y + pointC.y) / 2 + 5
                };
                ctx.fillText(`a = ${a.toFixed(1)}`, midBC.x, midBC.y);
                
                // 边AC (b)
                const midAC = {
                    x: (pointA.x + pointC.x) / 2 - 20,
                    y: (pointA.y + pointC.y) / 2 - 10
                };
                ctx.fillText(`b = ${b.toFixed(1)}`, midAC.x, midAC.y);
                
                // 标记角度
                ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
                ctx.font = 'italic 16px Arial';
                
                // 标记角A
                ctx.fillText(`∠A = ${(angleA * 180 / Math.PI).toFixed(1)}°`, pointA.x + 20, pointA.y - 15);
                
                // 标记角B
                ctx.fillText(`∠B = ${(angleB * 180 / Math.PI).toFixed(1)}°`, pointB.x - 60, pointB.y - 15);
                
                // 标记角C
                ctx.fillText(`∠C = ${(angleC * 180 / Math.PI).toFixed(1)}°`, pointC.x - 5, pointC.y + 30);
                
                // 如果是直角三角形，绘制直角标记
                if (angleType === '直角') {
                    drawRightAngleMarker(pointC, pointA, pointB, 20);
                }
                
                // 更新UI
                triangleTypeEl.textContent = triangleType;
                triangleTypeEl.className = "triangle-type " + angleType.toLowerCase();
                resultDetailsEl.textContent = description;
                visualInfoEl.textContent = `当前边长: a=${a.toFixed(1)}, b=${b.toFixed(1)}, c=${c.toFixed(1)} | 类型: ${triangleType}`;
            }
            
            function drawRightAngleMarker(vertex, point1, point2, size) {
                // 计算从顶点到两个点的向量
                const vec1 = { x: point1.x - vertex.x, y: point1.y - vertex.y };
                const vec2 = { x: point2.x - vertex.x, y: point2.y - vertex.y };
                
                // 标准化向量
                const len1 = Math.sqrt(vec1.x * vec1.x + vec1.y * vec1.y);
                const len2 = Math.sqrt(vec2.x * vec2.x + vec2.y * vec2.y);
                
                const norm1 = { x: vec1.x / len1, y: vec1.y / len1 };
                const norm2 = { x: vec2.x / len2, y: vec2.y / len2 };
                
                // 计算垂直点
                const markerPoint1 = {
                    x: vertex.x + norm1.x * size,
                    y: vertex.y + norm1.y * size
                };
                
                const markerPoint2 = {
                    x: vertex.x + norm2.x * size,
                    y: vertex.y + norm2.y * size
                };
                
                // 绘制直角标记
                ctx.beginPath();
                ctx.moveTo(markerPoint1.x, markerPoint1.y);
                ctx.lineTo(vertex.x + norm1.x * size + norm2.x * size, 
                           vertex.y + norm1.y * size + norm2.y * size);
                ctx.lineTo(markerPoint2.x, markerPoint2.y);
                ctx.strokeStyle = '#51cf66';
                ctx.lineWidth = 3;
                ctx.stroke();
            }
            
            // 事件监听器
            sideAInput.addEventListener('input', function() {
                a = parseFloat(sideAInput.value);
                updateSliderValues();
            });
            
            sideBInput.addEventListener('input', function() {
                b = parseFloat(sideBInput.value);
                updateSliderValues();
            });
            
            sideCInput.addEventListener('input', function() {
                c = parseFloat(sideCInput.value);
                updateSliderValues();
            });
            
            drawBtn.addEventListener('click', function() {
                drawTriangle();
            });
            
            // 预设按钮
            presetBtns.forEach(btn => {
                btn.addEventListener('click', function() {
                    a = parseFloat(this.dataset.a);
                    b = parseFloat(this.dataset.b);
                    c = parseFloat(this.dataset.c);
                    
                    sideAInput.value = a;
                    sideBInput.value = b;
                    sideCInput.value = c;
                    
                    updateSliderValues();
                    drawTriangle();
                });
            });
            
            // 初始绘制
            updateSliderValues();
            drawTriangle();
        });
    </script>
</body>
</html>